#include "Rect.h"
#include "Vector.h"
#include "Line.h"

namespace SkyEngine2d
{
	Rect::Rect(const Vector2& left_bottom_pos, const Size& size)
		: m_bottom(left_bottom_pos.y)
		, m_left(left_bottom_pos.x)
		, m_size(size)
	{
	}

	Rect::Rect()
		: m_left(0.0f)
		, m_bottom(0.0f)
	{
	}

	Rect::Rect(float left_bottom_x, float left_bottom_y, float width, float height)
		: m_left(left_bottom_x)
		, m_bottom(left_bottom_y)
		, m_size(width, height)
	{
	}

	Rect::Rect(float left_bottom_x, float left_bottom_y, const Size& size)
		: m_left(left_bottom_x)
		, m_bottom(left_bottom_y)
		, m_size(size)
	{
	}


	Rect::Rect(const Rect& rect)
		: m_left(rect.m_left)
		, m_bottom(rect.m_bottom)
		, m_size(rect.m_size)
	{
	}

	void Rect::move(const Vector2& dt)
	{
		this->move(dt.x, dt.y);
	}

	void Rect::move(float x_dt, float y_dt)
	{
		m_left += x_dt;
		m_bottom += y_dt;
	}

	void Rect::moveTo(const Vector2& pos)
	{
		this->moveTo(pos.x, pos.y);
	}

	void Rect::moveTo(float pos_x, float pos_y)
	{
		m_bottom = pos_y;
		m_left = pos_x;
	}

	bool Rect::containPoint(const Vector2& point) const
	{
		float x = point.x;
		float y = point.y;

		if (x > m_left && x<getRight() && y>m_bottom && y < getTop())
		{
			return true;
		}

		return false;
	}

	bool Rect::intersectWithLine(const Line& line) const
	{
		Vector2 br(getRight(), m_bottom);
		Vector2 tl(m_left, getTop());
		Vector2 tr(getRight(), getTop());
		Vector2 bl(m_left, m_bottom);

		Line a(bl, br);
		Line b(bl, tl);
		Line c(tl, tr);
		Line d(tr, br);

		if (line.lineIntersect(a) || line.lineIntersect(b) || line.lineIntersect(c) || line.lineIntersect(d))
		{
			return true;
		}

		return false;
	}

	bool Rect::intersectsWithRect(const Rect& rect) const
	{
		return
			!(
				m_left > rect.getRight() ||
				getTop() < rect.m_bottom ||
				rect.m_left > getRight() ||
				rect.getTop() < m_bottom
				);
	}

	Rect::operator D2D1_RECT_F()
	{
		D2D1_RECT_F  r;
		r.left = m_left;
		r.right = getRight();
		r.bottom = m_bottom;
		r.top = getTop();
		return r;
	}

	bool Rect::operator==(const Rect & r) const
	{
		if (m_bottom == r.m_bottom &&
			m_left == r.m_left &&
			m_size == r.m_size)
		{
			return true;
		}
		return false;
	}

	void Rect::setBottomLeft(const Vector2 & bottom_left)
	{
		m_bottom = bottom_left.y;
		m_left = bottom_left.x;
	}

	Rect Rect::Zero = Rect();

}

